using System;
using System.Threading;
using System.Threading.Tasks;

namespace Catastrophe.AutoSulution.ThreadM
{
	public class ThreadManager
	{
		private readonly ManualResetEvent _manualResetEvent = new ManualResetEvent(initialState: false);

		/// <summary>
		///     线程
		/// </summary>
		private Thread _td;

		/// <summary>
		///     开始线程
		/// </summary>
		/// <param name="tdHandler"></param>
		/// <param name="interval"></param>
		public void TdStart(Action tdHandler, int interval)
		{
			if (this._td == null)
			{
				this._td = new Thread((ThreadStart)delegate
				{
					this.TdFun(tdHandler, interval);
				})
				{
					IsBackground = true
				};
				this._td.Start();
			}
		}

		/// <summary>
		///     开始线程
		/// </summary>
		/// <typeparam name="T"></typeparam>
		/// <param name="tdHandler"></param>
		/// <param name="t"></param>
		/// <param name="interval"></param>
		public void TdStart<T>(Action<T> tdHandler, T t, int interval)
		{
			if (this._td == null)
			{
				this._td = new Thread((ThreadStart)delegate
				{
					this.TdFun(tdHandler, t, interval);
				})
				{
					IsBackground = true
				};
				this._td.Start();
			}
		}

		/// <summary>
		///     开始线程
		/// </summary>
		/// <typeparam name="T1"></typeparam>
		/// <typeparam name="T2"></typeparam>
		/// <param name="tdHandler"></param>
		/// <param name="t1"></param>
		/// <param name="t2"></param>
		/// <param name="interval"></param>
		public void TdStart<T1, T2>(Action<T1, T2> tdHandler, T1 t1, T2 t2, int interval)
		{
			if (this._td == null)
			{
				this._td = new Thread((ThreadStart)delegate
				{
					this.TdFun(tdHandler, t1, t2, interval);
				})
				{
					IsBackground = true
				};
				this._td.Start();
			}
		}

		/// <summary>
		///     线程函数
		/// </summary>
		/// <param name="tdHandler"></param>
		/// <param name="interval"></param>
		private void TdFun(Action tdHandler, int interval)
		{
			while (true)
			{
				this._manualResetEvent.WaitOne();
				tdHandler();
				Thread.Sleep(interval);
			}
		}

		/// <summary>
		///     线程函数
		/// </summary>
		/// <typeparam name="T"></typeparam>
		/// <param name="tdHandler"></param>
		/// <param name="t"></param>
		/// <param name="interval"></param>
		private void TdFun<T>(Action<T> tdHandler, T t, int interval)
		{
			while (true)
			{
				this._manualResetEvent.WaitOne();
				tdHandler(t);
				Thread.Sleep(interval);
			}
		}

		/// <summary>
		///     定时一段时间后执行任务（支持异步与同步）默认同步
		/// </summary>
		/// <param name="timeIntervalHandler">执行方法委托</param>
		/// <param name="waitTime">等待时间</param>
		/// <param name="isAsynFlag">是否异步</param>
		/// <param name="callBackHandler">回调委托</param>
		public void RunDelay(Action timeIntervalHandler, int waitTime, bool isAsynFlag = false, Action<Task> callBackHandler = null)
		{
			Thread thread = new Thread((ThreadStart)delegate
			{
				Thread.Sleep(waitTime);
				if (isAsynFlag && callBackHandler != null)
				{
					Task task = new Task(delegate
					{
						timeIntervalHandler();
					});
					task.ContinueWith(callBackHandler);
					task.Start();
				}
				else if (!isAsynFlag)
				{
					timeIntervalHandler();
				}
			});
			thread.IsBackground = true;
			thread.Start();
		}

		/// <summary>
		///     线程函数
		/// </summary>
		/// <typeparam name="T1"></typeparam>
		/// <typeparam name="T2"></typeparam>
		/// <param name="tdHandler"></param>
		/// <param name="t1"></param>
		/// <param name="t2"></param>
		/// <param name="interval"></param>
		private void TdFun<T1, T2>(Action<T1, T2> tdHandler, T1 t1, T2 t2, int interval)
		{
			while (true)
			{
				this._manualResetEvent.WaitOne();
				tdHandler(t1, t2);
				Thread.Sleep(interval);
			}
		}

		/// <summary>
		///     强制释放线程
		/// </summary>
		public void TdDispose()
		{
			if (this._td != null)
			{
				this._td.Abort();
				this._td = null;
			}
		}

		/// <summary>
		///     等待
		/// </summary>
		public void ManualWait()
		{
			this._manualResetEvent.Reset();
		}

		/// <summary>
		///     继续运行
		/// </summary>
		public void ManualContinue()
		{
			this._manualResetEvent.Reset();
		}

		/// <summary>
		///     线程挂起
		/// </summary>
		[Obsolete]
		public void TdSuspend()
		{
			this._td?.Suspend();
		}

		/// <summary>
		///     线程恢复
		/// </summary>
		[Obsolete]
		public void TdResume()
		{
			this._td?.Resume();
		}
	}
}
